#include <iostream>

#include <stdio.h>
#include <string.h>
#include <math.h>

#include <unistd.h>
#include <fcntl.h>
#include <cstdint>
#include <sys/stat.h>
#include <sys/mman.h>

#include "smart/smart_camera.hpp"
#include "libraw/libraw.h"
#include "clocker/clocker.h"

int main(const int argc, const char* argv[])
{
    SmartCamera cam("/dev/video0", 5, 1920, 1296, V4L2_PIX_FMT_SBGGR12);
    FILE* dst_file = fopen("./recv.rgb", "wb");
    if (dst_file == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    cam.loop_recv_frame([&cam, &dst_file](uint8_t *buf, uint32_t len){
        clocker_begin();

        LibRaw proc;
        static uint32_t frema_count{0};
        int ret;

        ret = proc.open_bayer(
            (unsigned char*)buf, 1920*1286*2,  // 缓冲区与大小
            1920, 1286, 0, 0, 0, 0,  // 图像尺寸与边距
            0,  // 过程标志
            LIBRAW_OPENBAYER_BGGR,  // 格式
            0,  // 未使用位数
            0,  // 保留标志
            100  // 黑电平值
        );
        if (ret != LIBRAW_SUCCESS) {
            fprintf(stderr, "Cannot open_bayer: %s\n", libraw_strerror(ret));
            exit(EXIT_FAILURE);
        }

        ret = proc.unpack();
        if (ret != LIBRAW_SUCCESS) {
            fprintf(stderr, "Cannot unpack: %s\n", libraw_strerror(ret));
            exit(EXIT_FAILURE);
        }

        proc.dcraw_process();
        if (ret != LIBRAW_SUCCESS) {
            fprintf(stderr, "Cannot dcraw_process: %s\n", libraw_strerror(ret));
            exit(EXIT_FAILURE);
        }

        libraw_processed_image_t *image = proc.dcraw_make_mem_image(&ret);
        if (!image) {
            fprintf(stderr, "Cannot dcraw_make_mem_image: %s\n", libraw_strerror(ret));
            exit(EXIT_FAILURE);
        }

        LOG_DEBUG("dcraw_make_mem_image seccess, image len:%d.", image->data_size);
        // fwrite(image->data, image->data_size, 1, dst_file);

        LibRaw::dcraw_clear_mem(image);
        if (++frema_count >= 100)
            cam.stop();
        clocker_end();
    });

    LOG_DEBUG("main_run end.");
    cam.deinit();
    fclose(dst_file);
    return 0;
}

